﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using AMVInfoSpace;

namespace AMVCommander
{
    public partial class FormLinkToSite : Form
    {
        public bool bOK = false;
        public string FPathLog = "";

        public FormLinkToSite()
        {
            InitializeComponent();

        }

        class NotMatchAMV
        {
            public string Name;
            public int DBInd;
            public int AMVInd;
            public AMV NewAmv = null;
            public AMVInfo AmvInf;
            public bool RecInBase = false;

            public NotMatchAMV(string Name, int DBInd, int AMVInd, AMV NewAmv, AMVInfo AmvInf)
            {
                this.Name = Name;
                this.DBInd = DBInd;
                this.AMVInd = AMVInd;
                this.NewAmv = NewAmv;
                this.AmvInf = AmvInf;
            }

            public override string ToString()
            {
                return string.Format("ID:{0}\t Имя файла: {1}, Имя с сайта: {2}", AMVInd, Name, AmvInf.Name);
            }
        }

        List<AMV> notFindLink = new List<AMV>();
        List<NotMatchAMV> notMatch = new List<NotMatchAMV>();
        Dictionary<int, AMV> linkAmv = new Dictionary<int, AMV>();

        private void FormLinkToSite_Shown(object sender, EventArgs e)
        {
            bOK = false;
            btnOk.Enabled = false;
            btnCancel.Enabled = false;
            chlbConflicts.Visible = false;
            FPathLog = "";
            label1.Text = "Идет выполнение ...";
            Application.DoEvents();

            // тег для привязываемых AMV для простого поиска и проверки привязаных записей
            string tagForAdd = "Привязка к AMVNews " + DateTime.Now.ToString("dd.MM.yy HH:mm");
            // загрузка инфо, если оно еще не загружено
            if (Gl.infoL.Count == 0) Gl.LoadAmvInfoList();

            notFindLink.Clear();
            notMatch.Clear();
            linkAmv.Clear();

            List<AMV> allAmvForLink = new List<AMV>();

            for (int i = 0; i < Gl.DB.Count; i++)
            {
                AMV amv = Gl.DB[i];

                if (!amv.IsPossableAMVNewsLink) continue;
                int amvNewsNum = amv.GetAMVNewsIdByFileName();

                // поиск по базе AmvInfo
                AMVInfo aInf = null;
                foreach (AMVInfo a in Gl.infoL) if (a.Site == SITE.AMVNews && a.Number == amvNewsNum) { aInf = a; break; }
                if (aInf == null)
                {
                    notFindLink.Add(amv);
                    continue;
                }

                // проверка имени
                string fName = amv.FullPath;
                int ind1 = fName.LastIndexOf('\\');
                int ind2 = fName.LastIndexOf('.');
                fName = fName.Substring(ind1 + 1, ind2 - ind1 - 1);
                List<string> SL = AMVInfo.SplitTextForFind(fName.Replace("amvnews.ru", "").Replace(amv.GetAMVNewsIdByFileName().ToString("00000"), ""));
                string INFO_NAME = aInf.Name.ToUpper();
                int matchCount = 0;
                foreach (string STR in SL) if (INFO_NAME.Contains(STR)) matchCount++;

                // если совпадение менее 50%, значит имя неверное
                bool bNotMatch = SL.Count > 0 && ((matchCount / (double)SL.Count) * 100.0) < 50;

                amv = amv.Clone();

                #region *** Копирование данных *********
                amv.Awd.Clear();
                amv.Atr.Clear();
                amv.Anm.Clear();
                amv.Msc.Clear();

                amv.Name = Gl.DB.GetUnicName(aInf.Name, amv, allAmvForLink.ToArray());
                amv.Sites.Add(SITE.AMVNews, new AMVSite(aInf.Number, aInf.Rating, aInf.GrabDate));
                amv.Comment = aInf.Comment;
                foreach (string str in aInf.TagGenre) if (!amv.Tags.Contains(str)) amv.Tags.Add(str);
                foreach (string str in aInf.TagOther) if (!amv.Tags.Contains(str)) amv.Tags.Add(str);
                if (!amv.Tags.Contains(tagForAdd)) amv.Tags.Add(tagForAdd);
                foreach (string str in aInf.Anm) if (!amv.Anm.Contains(str)) amv.Anm.Add(str);
                foreach (string str in aInf.Msc)
                {
                    string[] sl = str.Split(new char[1] { '-' }, 2);
                    sl[0] = sl[0].Trim();
                    if (sl.Length == 2)
                    {
                        sl[1] = sl[1].Trim();
                        bool bExist = false;
                        foreach (Music music in amv.Msc) if (music.Author == sl[0] && music.Name == sl[1]) { bExist = true; break; }
                        if (!bExist)
                        {
                            amv.Msc.Add(new Music(sl[0], sl[1]));
                        }
                    }
                    else
                    {
                        amv.Msc.Add(new Music("", str));
                    }
                }
                foreach (string str in aInf.Awd) if (!amv.Awd.Contains(str)) amv.Awd.Add(str);
                foreach (string str in aInf.Atr) if (!amv.Atr.Contains(str)) amv.Atr.Add(str);

                #endregion *** Копирование данных *********

                if (bNotMatch) notMatch.Add(new NotMatchAMV(fName, i, amv.GetAMVNewsIdByFileName(), amv, aInf));
                else linkAmv.Add(i, amv);
                allAmvForLink.Add(amv);
            }

            // если имеются конфликты по именам файлов, выводим их
            if (notMatch.Count > 0)
            {
                ShowNotMatch();
                return;
            }

            UpdateBase(false);
            Close();
        }

        void ShowNotMatch()
        {
            label1.Text = "Некоторые записи не привяжутся, поскольку имена файлов сильно не совпадают с именами на сайте. Выберете записи, которые все равно нужно сохранить";
            btnOk.Enabled = true;
            btnCancel.Enabled = true;
            chlbConflicts.Visible = true;
            chlbConflicts.Items.Clear();
            foreach (NotMatchAMV nmAmv in notMatch)
                chlbConflicts.Items.Add(nmAmv, false);
        }

        void UpdateBase(bool NotMatchChecked)
        {

            if (NotMatchChecked)
                foreach (NotMatchAMV nmAMV in chlbConflicts.CheckedItems)
                {
                    linkAmv.Add(nmAMV.DBInd, nmAMV.NewAmv);
                    notMatch.Remove(nmAMV);
                }

            // бэкап
            Backup.SaveBackup(Action.LinkToAMVNews);
            // копирование
            foreach (KeyValuePair<int, AMV> amv in linkAmv)
                Gl.DB[amv.Key].CopyFrom(amv.Value);
            // сохранение обновленной базы
            Gl.DB.Save();

            #region *** построение отчета *********

            string fPathLog = Gl.dPathLogs + "\\LinkLog " + DateTime.Now.ToString("dd.MM.yyyy HH_mm_ss") + ".log";
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Найдено аниме для привязки: " + (linkAmv.Count + notFindLink.Count + notMatch.Count).ToString());
            sb.AppendLine("Удачно привязано: " + linkAmv.Count.ToString());
            sb.AppendLine("Не найдена информация: " + notFindLink.Count);
            sb.AppendLine("Не привязано из за различий в именах: " + notMatch.Count.ToString());
            sb.AppendLine("--------------");
            if (notMatch.Count > 0)
            {
                sb.AppendLine("Список AMV, не привязанных из за различий в именах:");
                for (int i = 0; i < notMatch.Count; i++)
                    sb.AppendLine(string.Format("\t- ID: {0}\t Имя файла: {1}, Имя amvInfo: {2}", notMatch[i].AmvInf.Number, notMatch[i].Name, notMatch[i].AmvInf.Name));
            }
            if (notFindLink.Count > 0)
            {
                sb.AppendLine("Список AMV, с ненайденной информацией:");
                foreach (AMV amv in notFindLink)
                    sb.AppendLine(string.Format("\t- ID: {0}\t Имя файла: {1}", amv.GetAMVNewsIdByFileName(), amv.FLocalPath));
            }
            if (linkAmv.Count > 0)
            {
                sb.AppendLine("Список привязаных AMV:");
                foreach (KeyValuePair<int, AMV> amv in linkAmv)
                    sb.AppendLine(string.Format("\t- ID: {0}\t Имя файла: {1}", amv.Value.GetAMVNewsIdByFileName(), amv.Value.FLocalPath));
            }

            File.WriteAllText(fPathLog, sb.ToString(), Encoding.UTF8);
            FPathLog = fPathLog;
            #endregion *** построение отчета *********

            bOK = true;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            UpdateBase(true);
            Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

    }
}
